package com.jf.cloud.service.sysmanager.common.util;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.internet.MimeUtility;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;

/**
 * 字符串工具类
 * 
 * @author author 创建时间：2012-02-08 14:05:55
 */
public final class StringUtil { 

	/**
	 * 补全字符串
	 * 
	 * @author 程伟平 创建时间：2012-02-21 10:17:09
	 * @param str 源字符串
	 * @param fixChar 修补字符
	 * @param length 长度
	 * @return 补全字符串
	 */
	public static String fix(String str, String fixChar, int length) {
		StringBuffer sb = new StringBuffer();
		if (str != null && str.length() < length) {
			int count = length - str.length();
			for (int i = 0; i < count; i++) {
				sb.append(fixChar);
			}
			sb.append(str);
		}
		return sb.toString();
	}

	/**
	 * 获取字符串类名
	 * 
	 * @author 程伟平 2012-1-10
	 * @param str 字符串
	 * @return 类名
	 */
	public static String getClassName(String str) {
		if (str == null || str.length() == 0) {
			return str;
		}
		StringBuffer sb = new StringBuffer();

		String[] words = str.split("_");
		for (String word : words) {
			sb.append(getUpperCaseFirstCharacter(word));
		}

		return sb.toString();
	}

	/**
	 * 获取字符串对象名
	 * 
	 * @author 程伟平 2012-1-10
	 * @param str 字符串
	 * @return 对象名
	 */
	public static String getObjectName(String str) {
		if (str == null || str.length() == 0) {
			return str;
		}
		StringBuffer sb = new StringBuffer();

		String[] words = str.split("_");
		for (String word : words) {
			if (sb.length() > 0) {
				sb.append(getUpperCaseFirstCharacter(word));
			} else {
				sb.append(word.toLowerCase());
			}
		}

		return sb.toString();
	}

	/**
	 * 获取首字母大写单词
	 * 
	 * @author 程伟平 2012-1-9
	 * @param word 英文单词
	 * @return 首字母大写单词
	 */
	private static String getUpperCaseFirstCharacter(String word) {
		StringBuffer sb = new StringBuffer();
		// 大写首字母
		sb.append(word.substring(0, 1).toUpperCase());
		// 小写非首字母
		sb.append(word.substring(1).toLowerCase());
		return sb.toString();
	}

	/**
	 * 分割字符串
	 * 
	 * @param str 原始字符串
	 * @param separator 分隔符
	 * @return String[] 分割后的字符串数组
	 */
	public static String[] split(String str, String separator) {
		int index;
		if (str == null || separator == null) {
			return null;
		}
		List<String> list = new ArrayList<String>();
		while ((index = str.indexOf(separator)) != -1) {
			list.add(str.substring(0, index));
			str = str.substring(index + separator.length());
		}
		list.add(str);
		return list.toArray(new String[0]);
	}

	/**
	 * 将字符串数组转换成字符串
	 * 
	 * @author 程伟平 创建时间：2012-05-17 17:42:29
	 * @param strs 字符串数组
	 * @param separator 分隔符
	 * @return 字符串
	 */
	public static String convert(String[] strs, String separator) {
		StringBuffer sb = new StringBuffer();
		if (strs != null && strs.length > 0) {
			for (int i = 0; i < strs.length; i++) {
				if (sb.length() > 0) {
					sb.append(separator);
				}
				sb.append(strs[i]);
			}
		}
		return sb.toString();
	}

	/**
	 * 将字符串数组转换成字符串
	 * 
	 * @author 程伟平 创建时间：2012-05-17 17:42:29
	 * @param strs 字符串数组
	 * @param separator 分隔符
	 * @return 字符串
	 */
	public static String convert(List<String> strs, String separator) {
		StringBuffer sb = new StringBuffer();
		if (strs != null && strs.size() > 0) {
			for (int i = 0; i < strs.size(); i++) {
				if (sb.length() > 0) {
					sb.append(separator);
				}
				sb.append(strs.get(i));
			}
		}
		return sb.toString();
	}

	/**
	 * 替换字符串
	 * 
	 * @param from String 原始字符串
	 * @param to String 目标字符串
	 * @param source String 母字符串
	 * @return String 替换后的字符串
	 */
	public static String replace(String from, String to, String source) {
		if (source == null || from == null || to == null)
			return null;
		StringBuffer str = new StringBuffer("");
		int index = -1;
		while ((index = source.indexOf(from)) != -1) {
			str.append(source.substring(0, index) + to);
			source = source.substring(index + from.length());
			index = source.indexOf(from);
		}
		str.append(source);
		return str.toString();
	}

	/**
	 * 替换字符串，能能够在HTML页面上直接显示(替换双引号和小于号)
	 * 
	 * @param str String 原始字符串
	 * @return String 替换后的字符串
	 */
	public static String htmlencode(String str) {
		if (str == null) {
			return null;
		}
		return replace("\"", "&quot;", replace("<", "&lt;", str));
	}

	/**
	 * 替换字符串，将被编码的转换成原始码（替换成双引号和小于号）
	 * 
	 * @param str String
	 * @return String
	 */
	public static String htmldecode(String str) {
		if (str == null) {
			return null;
		}

		return replace("&quot;", "\"", replace("&lt;", "<", str));
	}

	/**
	 * 在页面上直接显示文本内容，替换小于号，空格，回车，TAB
	 * 
	 * @param str String 原始字符串
	 * @return String 替换后的字符串
	 */
	public static String htmlshow(String str) {
		if (str == null) {
			return null;
		}

		str = replace("<", "&lt;", str);
		str = replace(" ", "&nbsp;", str);
		str = replace("\r\n", "<br/>", str);
		str = replace("\n", "<br/>", str);
		str = replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;", str);
		return str;
	}

	/**
	 * 返回指定字节长度的字符串
	 * 
	 * @param str String 字符串
	 * @param length int 指定长度
	 * @return String 返回的字符串
	 */
	public static String toLength(String str, int length) {
		if (str == null) {
			return null;
		}
		if (length <= 0) {
			return "";
		}
		try {
			if (str.getBytes("GBK").length <= length) {
				return str;
			}
		} catch (Exception e) {
		}
		StringBuffer buff = new StringBuffer();

		int index = 0;
		char c;
		length -= 3;
		while (length > 0) {
			c = str.charAt(index);
			if (c < 128) {
				length--;
			} else {
				length--;
				length--;
			}
			buff.append(c);
			index++;
		}
		buff.append("...");
		return buff.toString();
	}

	/**
	 * 是否为空
	 * 
	 * @author 程伟平 创建时间：2013-03-13 09:27:12
	 */
	public static boolean isEmpty(String str) {
		return str == null || str.trim().length() == 0;
	}

	/**
	 * 是否为空
	 * 
	 * @author 姚龙 创建时间：2013-10-24 10:07:12
	 */
	public static boolean isEmpty(Object str) {
		return str == null || "".equals(str);
	}

	/**
	 * 是否非空
	 * 
	 * @author 程伟平 创建时间：2013-03-13 09:27:12
	 */
	public static boolean isNotEmpty(String str) {
		return str != null && str.trim().length() > 0;
	}

	/**
	 * 是否为空
	 * 
	 * @author 程伟平 创建时间：2013-03-13 09:27:12
	 */
	public static boolean isNull(String str) {
		return str == null || str.trim().length() == 0 || "null".equals(str.trim());
	}
	
	/**
	 * 判断是否为整数
	 * 
	 * @param str 传入的字符串
	 * @return 是整数返回true,否则返回false
	 */
	public static boolean isInteger(String str) {
		Pattern pattern = Pattern.compile("^[-\\+]?[\\d]+$");
		return pattern.matcher(str).matches();
	}

	/**
	 * 判断是否为浮点数，包括double和float
	 * 
	 * @param str 传入的字符串
	 * @return 是浮点数返回true,否则返回false
	 */
	public static boolean isDouble(String str) {
		Pattern pattern = Pattern.compile("^[-\\+]?\\d+\\.\\d+$");
		return pattern.matcher(str).matches();
	}

	/**
	 * 判断是不是合法字符 c 要判断的字符
	 */
	public static boolean isLetter(String str) {
		if (str == null || str.length() < 0) {
			return false;
		}
		Pattern pattern = Pattern.compile("[\\w\\.-_]*");
		return pattern.matcher(str).matches();
	}

	/**
	 * 从指定的字符串中提取Email content 指定的字符串
	 * 
	 * @param content
	 * @return
	 */
	public static String parse(String content) {
		String email = null;
		if (content == null || content.length() < 1) {
			return email;
		}
		// 找出含有@
		int beginPos;
		int i;
		String token = "@";
		String preHalf = "";
		String sufHalf = "";

		beginPos = content.indexOf(token);
		if (beginPos > -1) {
			// 前项扫描
			String s = null;
			i = beginPos;
			while (i > 0) {
				s = content.substring(i - 1, i);
				if (isLetter(s))
					preHalf = s + preHalf;
				else
					break;
				i--;
			}
			// 后项扫描
			i = beginPos + 1;
			while (i < content.length()) {
				s = content.substring(i, i + 1);
				if (isLetter(s))
					sufHalf = sufHalf + s;
				else
					break;
				i++;
			}
			// 判断合法性
			email = preHalf + "@" + sufHalf;
			if (isEmail(email)) {
				return email;
			}
		}
		return null;
	}

	/**
	 * 判断输入的字符串是否符合Email样式.
	 * 
	 * @param email 传入的字符串
	 * @return 是Email样式返回true,否则返回false
	 */
	public static boolean isEmail(String email) {
		if (email == null || email.length() < 1 || email.length() > 256) {
			return false;
		}
		Pattern pattern = Pattern.compile("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");
		return pattern.matcher(email).matches();
	}

	/**
	 * 判断输入的字符串是否为纯汉字
	 * 
	 * @param str 传入的字符窜
	 * @return 如果是纯汉字返回true,否则返回false
	 */
	public static boolean isChinese(String str) {
		Pattern pattern = Pattern.compile("[\u0391-\uFFE5]+$");
		return pattern.matcher(str).matches();
	}

	/**
	 * 是否为空白,包括null和""
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isBlank(String str) {
		return str == null || str.trim().length() == 0;
	}
	
	/**
	 * 是否为图片
	 * 
	 * @author 朱建文 创建时间：2017年12月9日 下午5:26:40
	 */
	public static boolean isImg(String str) {
		Pattern pattern = Pattern.compile(".+(.JPEG|.jpeg|.JPG|.jpg|.BMP|.bmp|.gif|.png|.GIF|.PNG)$");
		return pattern.matcher(str).matches();
    }
	
	/**
	 * 判断是否为质数
	 * 
	 * @param x
	 * @return
	 */
	public static boolean isPrime(int x) {
		if (x <= 7) {
			if (x == 2 || x == 3 || x == 5 || x == 7)
				return true;
		}
		int c = 7;
		if (x % 2 == 0)
			return false;
		if (x % 3 == 0)
			return false;
		if (x % 5 == 0)
			return false;
		int end = (int) Math.sqrt(x);
		while (c <= end) {
			if (x % c == 0) {
				return false;
			}
			c += 4;
			if (x % c == 0) {
				return false;
			}
			c += 2;
			if (x % c == 0) {
				return false;
			}
			c += 4;
			if (x % c == 0) {
				return false;
			}
			c += 2;
			if (x % c == 0) {
				return false;
			}
			c += 4;
			if (x % c == 0) {
				return false;
			}
			c += 6;
			if (x % c == 0) {
				return false;
			}
			c += 2;
			if (x % c == 0) {
				return false;
			}
			c += 6;
		}
		return true;
	}

	/**
	 * 人民币转成大写
	 * 
	 * @param str 数字字符串
	 * @return String 人民币转换成大写后的字符串
	 */
	public static String hangeToBig(String str) {
		double value;
		try {
			value = Double.parseDouble(str.trim());
		} catch (Exception e) {
			return null;
		}
		char[] hunit = { '拾', '佰', '仟' }; // 段内位置表示
		char[] vunit = { '万', '亿' }; // 段名表示
		char[] digit = { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' }; // 数字表示
		long midVal = (long) (value * 100); // 转化成整形
		String valStr = String.valueOf(midVal); // 转化成字符串

		String head = valStr.substring(0, valStr.length() - 2); // 取整数部分
		String rail = valStr.substring(valStr.length() - 2); // 取小数部分

		String prefix = ""; // 整数部分转化的结果
		String suffix = ""; // 小数部分转化的结果
		// 处理小数点后面的数
		if (rail.equals("00")) { // 如果小数部分为0
			suffix = "整";
		} else {
			suffix = digit[rail.charAt(0) - '0'] + "角" + digit[rail.charAt(1) - '0'] + "分"; // 否则把角分转化出来
		}
		// 处理小数点前面的数
		char[] chDig = head.toCharArray(); // 把整数部分转化成字符数组
		char zero = '0'; // 标志'0'表示出现过0
		byte zeroSerNum = 0; // 连续出现0的次数
		for (int i = 0; i < chDig.length; i++) { // 循环处理每个数字
			int idx = (chDig.length - i - 1) % 4; // 取段内位置
			int vidx = (chDig.length - i - 1) / 4; // 取段位置
			if (chDig[i] == '0') { // 如果当前字符是0
				zeroSerNum++; // 连续0次数递增
				if (zero == '0') { // 标志
					zero = digit[0];
				} else if (idx == 0 && vidx > 0 && zeroSerNum < 4) {
					prefix += vunit[vidx - 1];
					zero = '0';
				}
				continue;
			}
			zeroSerNum = 0; // 连续0次数清零
			if (zero != '0') { // 如果标志不为0,则加上,例如万,亿什么的
				prefix += zero;
				zero = '0';
			}
			prefix += digit[chDig[i] - '0']; // 转化该数字表示
			if (idx > 0)
				prefix += hunit[idx - 1];
			if (idx == 0 && vidx > 0) {
				prefix += vunit[vidx - 1]; // 段结束位置应该加上段名如万,亿
			}
		}

		if (prefix.length() > 0)
			prefix += '圆'; // 如果整数部分存在,则有圆的字样
		return prefix + suffix; // 返回正确表示
	}

	/**
	 * 过滤特殊字符
	 * 
	 * @param src
	 * @return
	 */
	public static String encoding(String src) {
		if (src == null)
			return "";
		StringBuilder result = new StringBuilder();
		if (src != null) {
			src = src.trim();
			for (int pos = 0; pos < src.length(); pos++) {
				switch (src.charAt(pos)) {
				case '\"':
					result.append("&quot;");
					break;
				case '<':
					result.append("&lt;");
					break;
				case '>':
					result.append("&gt;");
					break;
				case '\'':
					result.append("&apos;");
					break;
				case '&':
					result.append("&amp;");
					break;
				case '%':
					result.append("&pc;");
					break;
				case '_':
					result.append("&ul;");
					break;
				case '#':
					result.append("&shap;");
					break;
				case '?':
					result.append("&ques;");
					break;
				default:
					result.append(src.charAt(pos));
					break;
				}
			}
		}
		return result.toString();
	}

	/**
	 * 判断是不是合法的手机号码
	 * 
	 * @param handset
	 * @return boolean
	 */
	public static boolean isHandset(String handset) {
		try {
			String regex = "^1[\\d]{10}$";
			Pattern pattern = Pattern.compile(regex);
			Matcher matcher = pattern.matcher(handset);
			return matcher.matches();

		} catch (RuntimeException e) {
			return false;
		}
	}

	/**
	 * 反过滤特殊字符
	 * 
	 * @param src
	 * @return
	 */
	public static String decoding(String src) {
		if (src == null)
			return "";
		String result = src;
		result = result.replace("&quot;", "\"").replace("&apos;", "\'");
		result = result.replace("&lt;", "<").replace("&gt;", ">");
		result = result.replace("&amp;", "&");
		result = result.replace("&pc;", "%").replace("&ul", "_");
		result = result.replace("&shap;", "#").replace("&ques", "?");
		return result;
	}

	/**
	 * 字符串 非空判断
	 * 
	 * @author ouyang 创建时间：Feb 16, 2012 5:56:57 AM
	 * @param str
	 * @return
	 */
	public static boolean notNull(String str) {
		return str != null && str.trim().length() > 0;
	}

	/**
	 * 
	 * TODO ISO 装换 GBK
	 * 
	 * @author duaichao 创建时间：2012-03-21 16:57:37
	 * @param str
	 * @return
	 */
	public static String convertGBK(String str) {
		try {
			return str;
		} catch (Exception e) {
			return "";
		}
	}

	public static String unescape(String src) {
		if (src == null)
			return null;
		StringBuffer tmp = new StringBuffer();
		tmp.ensureCapacity(src.length());
		int lastPos = 0, pos = 0;
		char ch;
		while (lastPos < src.length()) {
			pos = src.indexOf("%", lastPos);
			if (pos == lastPos) {
				if (src.charAt(pos + 1) == 'u') {
					ch = (char) Integer.parseInt(src.substring(pos + 2, pos + 6), 16);
					tmp.append(ch);
					lastPos = pos + 6;
				} else {
					ch = (char) Integer.parseInt(src.substring(pos + 1, pos + 3), 16);
					tmp.append(ch);
					lastPos = pos + 3;
				}
			} else {
				if (pos == -1) {
					tmp.append(src.substring(lastPos));
					lastPos = src.length();
				} else {
					tmp.append(src.substring(lastPos, pos));
					lastPos = pos;
				}
			}
		}
		return tmp.toString();
	}

	/**
	 * 
	 * TODO ISO 装换 UTF-8
	 * 
	 * @author duaichao 创建时间：2012-03-21 16:57:37
	 * @param str
	 * @return
	 */
	public static String convertUTF8(String str) {
		try {
			return new String(str.getBytes("ISO-8859-1"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return "";
		}
	}

	public static String null2String(Object obj) {
		return obj == null ? "" : obj.toString();
	}

	/**
	 * 设置下载文件中文件的名称
	 * 
	 * @param filename
	 * @param request
	 * @return
	 */
	public static String encodeFilename(String filename, HttpServletRequest request) {
		/**
		 * 获取客户端浏览器和操作系统信息 在IE浏览器中得到的是：User-Agent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; Alexa
		 * Toolbar) 在Firefox中得到的是：User-Agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.7.10) Gecko/20050717
		 * Firefox/1.0.6
		 */
		String agent = request.getHeader("USER-AGENT");
		try {
			if ((agent != null) && (-1 != agent.indexOf("MSIE") || -1 != agent.indexOf("Trident"))) {
				String newFileName = URLEncoder.encode(filename, "UTF-8");
				newFileName = StringUtils.replace(newFileName, "+", "%20");
				if (newFileName.length() > 150) {
					newFileName = new String(filename.getBytes("GB2312"), "ISO8859-1");
					newFileName = StringUtils.replace(newFileName, " ", "%20");
				}
				return newFileName;
			}
			if ((agent != null) && (-1 != agent.indexOf("Mozilla")))
				return MimeUtility.encodeText(filename, "UTF-8", "B");

			return filename;
		} catch (Exception ex) {
			return filename;
		}
	}
	
	public static boolean checkWords(String str) {
		String regEx = "[\\w]*";
	    Pattern pat = Pattern.compile(regEx);
	    Matcher mat = pat.matcher(str);
	    return mat.matches();
	}
	
	
	/**
	 * 把空格替换成"+"
	 * @author ZhaiYuanling 创建时间：2016年7月6日 下午7:41:02
	 */
	public static String replaceSpace(String str){
        Pattern p = Pattern.compile("\\s");
		Matcher m = p.matcher(str);
		if (m.find()) {
			str = str.replaceAll("\\s", "+");
		}
		return str;
	}
	
	/**
	 * 把空格替换成""
	 * @author ZhaiYuanling 创建时间：2016年7月6日 下午7:41:02
	 */
	public static String deleSpace(String str){
        Pattern p = Pattern.compile("\\s");
		Matcher m = p.matcher(str);
		if (m.find()) {
			str = str.replaceAll("\\s", "");
		}
		return str;
	}
	

}
